package org.argus.common.core.json;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.NumberSerializers;

import java.io.IOException;

/**
 * Long Json序列化器，解决前端JavaScript number的最大安全值 丢失精度问题<br/>
 * 
 * @Author 刘文/Cliff Liu
 * @Date 2024/10/26
 */
public class LongJavaScriptSafeSerializer extends NumberSerializers.Base<Object> {

    /**
     * JavaScript number的最大安全值——9007199254740992（2的53次方） 如果超过这个值，那么js会出现丢失精度的问题
     */
    public static final long JAVASCRIPT_SAFE_LONG = 9007199254740992L;
    /**
     * Singleton instance to use.
     */
    public final static LongJavaScriptSafeSerializer instance = new LongJavaScriptSafeSerializer();

    public LongJavaScriptSafeSerializer() {
        super(Long.class, JsonParser.NumberType.LONG, "number");
    }

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        // null值序列化成null，避免空指针异常
        if (value == null) {
            provider.defaultSerializeNull(gen);
            return;
        }

        long longVal = ((Long)value).longValue();
        // 小于等于Java Script安全精度序列化成数字
        if (longVal <= JAVASCRIPT_SAFE_LONG) {
            gen.writeNumber(longVal);
        }
        // 大于Java Script安全精度序列化成字符串
        else {
            gen.writeString(String.valueOf(longVal));
        }
    }
}
